const { ENUM_CACHE_TYPE } = require("../../../static/enum");
const CacheConfigItem = require("./cacheConfigItem");

module.exports = class CacheTableItem extends CacheConfigItem {
	/**
	 * 构造函数
	 * 用于初始化缓存对象
	 * 
	 * @param {Object} param - 初始化参数
	 *        - data: 缓存的数据，默认为null
	 */
	constructor(param) {
		// 父类初始化
	    super(param);
	    const {
	        data = null,
	    } = param || {}
	    this.data = data; // 缓存的数据
	
	    this.createTime = new Date().getTime(); // 缓存创建时间 时间戳
	}

	/**
	 * 初始化缓存数据
	 */
	initData() {
		if (this.type == ENUM_CACHE_TYPE.STORAGE.value) {
			// storage 中的数据，初始化时需要提取并处理后转存至内存中
			// 1. 读取 storage中 数据
			let storageData = getStorageSyncFn()(this.key);
			if (storageData) {
				// 2. 判断是否有过期时限，并且是否过期
				if (this.expireTime && new Date().getTime() - this.expireTime > storageData.createTime) {
					// 2.1 如果有过期时限，并且已经超出过期时限，则清空数据，并更新 storage
					setStorageSyncFn()(this.key, this);
				} else {
					// 2.2 如果无过期时限或未过期，则转存至内存
					this.data = storageData.data;
					this.createTime = storageData.createTime;
				}
			} else {
				// 3. 如果不存在，则为全新数据，直接新增 storage
				setStorageSyncFn()(this.key, this);
			}
		} else if (this.type == ENUM_CACHE_TYPE.MEMORY.value) {
			// 内存中的数据，初始化时不需要做任何处理，本身就是空的
		} else {
			throw new Error("initCacheTable cacheTabelItem type is wrong")
		}
	}

	/**
	 * 更新缓存数据
	 * @param {Any} data 需要更新的数据
	 */
	updateCacheData(data) {
		this.data = data;
		this.createTime = new Date().getTime();
		if (this.type == ENUM_CACHE_TYPE.STORAGE.value) {
			// storage 中的数据，需要更新 storage
			setStorageSyncFn()(this.key, this);
		} else if (this.type == ENUM_CACHE_TYPE.MEMORY.value) {
			// 内存中的数据，需要更新内存
		} else {
			throw new Error("cacheData cacheTabelItem type is wrong")
		}
	}

	/**
	 * 读取缓存数据
	 * @returns {Any} 缓存数据
	 */
	readCacheData() {
		// 1. 判断缓存数据是否存在
		if (this.data) {
			// 2. 判断缓存数据是否有过期时限 并且是否过期
			if (this.expireTime && new Date().getTime() - this.expireTime > this.createTime) {
				// 2.1 如果有过期时限，并且已经超出过期时限，则清空数据，并返回 null
				this.data = null;
				// 2.1.1 如果是 storage 类型，则更新 storage
				if (this.type == 'storage') {
					setStorageSyncFn()(this.key, this);
				}
			} else {
				// 2.2 如果没有过期时限，或者未过期，则返回缓存数据
			}
		}
		return this.data;
	}
}

/**
 * 根据不同的环境类型，返回对应的本地存储设置方法
 * 
 * @returns {Function} - 根据环境类型返回对应的本地存储设置函数
 * @throws {Error} - 如果提供的环境类型不正确，则抛出错误
 */
function setStorageSyncFn() {
    return uni.setStorageSync;
}

/**
 * 根据不同的环境类型获取对应的本地存储同步获取方法
 * 
 * @returns {Function} 返回对应环境的本地存储同步获取方法
 * @throws {Error} 如果提供的环境类型不正确，则抛出错误
 */
function getStorageSyncFn() {
    return uni.getStorageSync;
}